#pragma once

#include "ConsolePrerequisites.h"
#include "LexicalCast.h"

class IValue
{
public:
	virtual csString	Get() const = 0;
	virtual void		Set( const csString & v ) = 0;
	virtual void		Reset() = 0;
	virtual csString	Default() = 0;
};

template<typename T>
class CValue : public IValue
{
public:
	typedef T value_type;

	CValue( const value_type & v )
	{
		m_CurrentValue = v;
		m_DefaultValue = v;
	}

	virtual csString	Get() const
	{
		return LexicalCast<csString>( m_CurrentValue );
	}

	virtual void		Set( const csString & v )
	{
		_Set( LexicalCast<value_type>( v ) );
	}

	virtual void		Reset()
	{
		_Set( m_DefaultValue );
	}

	virtual csString	Default()
	{
		return LexicalCast<csString>( m_DefaultValue );
	}

	//////////////////////////////////////////////////////////////////////////


	// operators
	operator			const value_type() const				{ return m_CurrentValue; }
	void 				operator = ( const value_type & v )		{ _Set(v); }

protected:
	virtual void OnChanged( const value_type & value ){}

private:
	virtual void _Set( const value_type & v )
	{
		value_type before = m_CurrentValue;
		m_CurrentValue = v;
		if ( before != m_CurrentValue )
			OnChanged(m_CurrentValue);
	}

private:
	value_type	m_CurrentValue;
	value_type	m_DefaultValue;

};


